/***************************************************************************
 *   Copyright (C) 2008 by Ryszard Krol,   *
 *   rysiek.krol@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "rexifdata.h"
#include <cassert>


#include <QFileInfo>
#include <QImage>
#include <QSize>

/**
* Konstruktor Klasy
*/
RExifData::RExifData ( char* filePath )
{
        	this->filePathString = QString::fromAscii(filePath);
 try {
                this->image = Exiv2::ImageFactory::open ( filePath );
                //assert ( image.get() != 0 );
                image->readMetadata();
                this->exifData = image->exifData();
                if ( !this->exifData.empty() ) {
                        this->extractThumbnail();
                        this->extractDateTime();
                        this->isNull = false;
                } else {
                        this->isNull = true;
                }
        } catch (Exiv2::AnyError& error) {
                this->isNull = true;
        }
}

/**
* Konstruktor Klasy
*/
RExifData::RExifData ( QString *filePath )
{
	RExifData ( filePath->toUtf8().data() );
        delete filePath;
}

/**
* Destruktor Klasy
*/
RExifData::~RExifData()
{
//delete this->filePathString;
}

/**
* Zwraca true, jeśli w pliku są dane EXIF, lub false, gdy takich danych nie ma
*/
bool RExifData::isExif()
{
	if (this->isNull==true) return false;
	return !this->exifData.empty();
}

/**
* Wyciąga date zrobienia zdjęcia z danych EXIF
*/
void RExifData::extractDateTime()
{
        Exiv2::ExifKey* klucz = '\0';
        if (this->isKeyExist("Exif.Photo.DateTimeOriginal")) klucz = new Exiv2::ExifKey ( "Exif.Photo.DateTimeOriginal" );
        if (this->isKeyExist("Exif.Image.DateTime")) klucz = new Exiv2::ExifKey ( "Exif.Image.DateTime" );
        if (klucz!='\0') {
                Exiv2::ExifData::iterator itsIterator = this->exifData.findKey ( *klucz );
                this->date = QDateTime::fromString ( QString::fromStdString ( itsIterator->value().toString() ), "yyyy:MM:dd hh:mm:ss" );
                delete klucz;
        }
}

/**
* Wyciąga miniaturke z danych EXIF
*/
void RExifData::extractThumbnail()
{
	std::pair< uchar *, long > data;
	Exiv2::ExifThumb *exifThumb = new Exiv2::ExifThumb(this->exifData);
	Exiv2::DataBuf  buffer = exifThumb->copy();
	data = buffer.release();
	this->thumbnail.loadFromData ( data.first, data.second ); 
	delete exifThumb;
	delete data.first;

	

}

/**
* Zwraca date zrobienia zdjęcia
*/
QDateTime RExifData::getDate()
{
	return this->date;
}

/**
* Zwraca miniaturke zdjęcia
*/
QImage RExifData::getThumbnail()
{
	return this->thumbnail;
}

/**
* Sprawdza, czy dany klucz istnieje w danych EXIF pliku
*/
bool RExifData::isKeyExist(std::string klucz){
	Exiv2::ExifData::const_iterator end = exifData.end();
	for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {

		if(i->key()==klucz) return true;
	}
	return false;
}

void RExifData::writeData()
{

                if( image.get() != 0 ){
                this->refreshImageThumbnail();
                this->image->setExifData(this->exifData);
                this->image->writeMetadata();
		}

}

/**
* Robi oraz zapisuje nowego thumbnaila na podstawie zdjęcia
*/
void RExifData::refreshImageThumbnail()
{
	QFileInfo *tmpfile = new QFileInfo("tmpfile.jpg");
	QImage *thumbnail = new QImage(this->filePathString);
	*thumbnail = thumbnail->scaled( QSize(100,100), Qt::KeepAspectRatio, Qt::SmoothTransformation);
	thumbnail->save(tmpfile->absoluteFilePath());
	Exiv2::ExifThumb *exifThumb = new Exiv2::ExifThumb(this->exifData);
	exifThumb->setJpegThumbnail(tmpfile->absoluteFilePath().toStdString());
	QFile(tmpfile->absoluteFilePath()).remove();
	delete exifThumb;
	delete tmpfile;
	delete thumbnail;
}

/**
  *Returns Exif data formated for QTreeWidget
  */
QList<QTreeWidgetItem *> * RExifData::getExifTree(){
       QList<QTreeWidgetItem *> *list = new QList<QTreeWidgetItem *>();
        Exiv2::ExifData::const_iterator end = exifData.end();
        for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
            QTreeWidgetItem *groupItem = this->groupExists(i->groupName(), list);
            if(groupItem=='\0' && i->groupName()!="Thumbnail"){
                QTreeWidgetItem *item = new QTreeWidgetItem(0);
                item->setText(0, QString::fromStdString(i->groupName()));
                QTreeWidgetItem *itemChild = new QTreeWidgetItem(0);
                itemChild->setText(0,QString::fromStdString(i->tagName()));
                itemChild->setText(1,QString::fromStdString(i->toString()));
                item->addChild(itemChild);
                list->append(item);
            } else {
                if(groupItem!='\0'){
                    QTreeWidgetItem *item = new QTreeWidgetItem(0);
                    item->setText(0, QString::fromStdString(i->tagName()));
                    item->setText(1, QString::fromStdString(i->toString()));
                    groupItem->addChild(item);
                }
            }
        }
       return list;
}

/**
  * Checks, if group name already exsist
  */
QTreeWidgetItem * RExifData::groupExists(std::string groupName,  QList<QTreeWidgetItem *> *list){
    QString *name = new QString(QString::fromStdString(groupName));
    QTreeWidgetItem *ret ='\0';
    for(int i = 0;i<list->count(); i++){
        if(list->at(i)->text(0)==name){
            ret = list->value(i);
            break;
        }
    }
    delete name;
    return ret;
}
